#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "common.h"
#include "ecu.h"
#include "gateway.h"
#include "CCL.h"

#define AUTH_REQUEST (0x30)
#define AUTH_RESPONSE (0x31)
#define AUTH_VERIFY (0x32)

AUTH_response rebuild_response;
AUTH_verify rebuild_verify;
int rebuild_count = 0;
int rebuild_count1 = 0;

void send_can_frame(unsigned char* message, int length, unsigned char frame_id);
void OnCanMessage0x30(struct cclCanMessage* message);
void OnCanMessage0x31(struct cclCanMessage* message);
void OnCanMessage0x32(struct cclCanMessage* message);

void OnMeasurementPreStart()
{
    int32_t rc;
    rc = cclCanSetMessageHandler(1, cclCanMakeStandardIdentifier(0x30), &OnCanMessage0x30);
    rc = cclCanSetMessageHandler(1, cclCanMakeStandardIdentifier(0x31), &OnCanMessage0x31);
    rc = cclCanSetMessageHandler(1, cclCanMakeStandardIdentifier(0x32), &OnCanMessage0x32);
}

void OnMeasurementStart()
{
    unsigned char id[2] = { 0x00,0x22 };
    srand((unsigned) time(NULL));;
    unsigned char key[KEY_LENGTH_BYTES];
    for(int i=0;i<KEY_LENGTH_BYTES;++i)
    {
        key[i]=rand()%255;
    }
    ecu_reg(id,key);
    gw_reg(id,key);

    AUTH_request request = gw_auth_req();
    send_can_frame((unsigned char*)&request, sizeof(request), AUTH_REQUEST);
}

void OnCanMessage0x30(struct cclCanMessage* message)
{
    AUTH_request request;
    memcpy(&request.r1, message->data + 1, SIZE_INT);
    AUTH_response response = ecu_auth_response(request);
    send_can_frame((unsigned char*)&response, sizeof(response), AUTH_RESPONSE);
}

void OnCanMessage0x31(struct cclCanMessage* message)
{
    memcpy((unsigned char*)&rebuild_response + (message->data[0]) * 7, message->data + 1, message->dataLength - 1);
    if (rebuild_count == sizeof(rebuild_response)/7)
    {
        AUTH_verify a_verify = gw_auth_verify(rebuild_response);
        send_can_frame((unsigned char*)&a_verify, sizeof(a_verify), AUTH_VERIFY);
    }
    else
    {
        rebuild_count++;
    }
}

void OnCanMessage0x32(struct cclCanMessage* message)
{
    memcpy((unsigned char*)&rebuild_verify + (message->data[0]) * 7, message->data + 1, message->dataLength - 1);
    if (rebuild_count1 == sizeof(rebuild_verify)/7)
    {
        ecu_auth_confirm(rebuild_verify);
    }
    else
    {
        rebuild_count1++;
    }
}

void cclOnDllLoad()
{
    cclSetMeasurementPreStartHandler(&OnMeasurementPreStart);
    cclSetMeasurementStartHandler(&OnMeasurementStart);
}





void send_can_frame(unsigned char* message, int length, unsigned char frame_id)
{
    unsigned char buffer[8] = { 0 };
    int rc = 0;
    int id = cclCanMakeStandardIdentifier(frame_id);
    if (length <= 7)
    {
        buffer[0] = 0;
        memcpy(buffer + 1, message, length);
        rc = cclCanOutputMessage(1, id, 0, length + 1, buffer);
    }
    else
    {
        int frame_num = (length / 7);
        for (int i = 0; i < frame_num; ++i)
        {
            buffer[0] = i;
            memcpy(buffer + 1, message + 7 * i, 7);
            rc = cclCanOutputMessage(1, id, 0, 8, buffer);
        }
        memset(buffer, 0, 8);
        buffer[0] = frame_num;
        memcpy(buffer + 1, message + 7 * frame_num, length - (7 * frame_num));
        rc = cclCanOutputMessage(1, id, 0, length - (7 * frame_num) + 1, buffer);
    }
}




//int main()
//{
//    printf("Hello, World!\n");
//    srand((unsigned) time(NULL));
//    unsigned char ID[2]={0,96};
//    unsigned char key[KEY_LENGTH_BYTES];
//    for(int i=0;i<KEY_LENGTH_BYTES;++i)
//    {
//        key[i]=rand()%255;
//    }
//    ecu_reg(ID,key);
//    gw_reg(ID,key);
//
//    AUTH_request request;
//    AUTH_response response;
//    AUTH_verify verify;
//    request=gw_auth_req();
//    response= ecu_auth_response(request);
//    verify= gw_auth_verify(response);
//    ecu_auth_confirm(verify);
//
//    return 0;
//}
